home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 21 / CU Amiga Magazine's Super CD-ROM 21 (1998)(EMAP Images)(GB)[!][issue 1998-04].iso / CUCD / Programming / PPCcforth / forth.doc < prev    next >
Text File  |  1985-12-27  |  28KB  |  640 lines

  1. C-FORTH: a portable, C-coded figFORTH interpreter.
  2.  
  3. Written by Allan Pratt; completed April 1985.
  4.  
  5. This is a FORTH interpreter written entirely in portable C and FORTH. It
  6. requires nothing more than a decent C compiler to use.  It is not exactly
  7. fast or efficient, but it is a true FORTH interpreter.
  8.  
  9. The features include:
  10.  
  11. Bootstrapping threaded definitions from a near-FORTH dictionary file.
  12. Block file I/O.
  13. Execution tracing and single-stepping.
  14. Breakpoint detection, dumping the stack at the breakpoint.
  15. Saving and automatic restoration of the FORTH environment.
  16. Ability to convert the block file to a line-editor-compatible file, and back.
  17.  
  18. Included with the interpreter is a block file containing:
  19.  
  20. An UNTHREAD utility.
  21. A screen editor with key-binding and cursor-addressing.
  22.  
  23.  
  24. BRINGING UP THE INTERPRETER:
  25.  
  26. THIS FORTH MODEL REQUIRES "int"s TO BE TWICE THE SIZE OF "short"s,
  27. and "short"s to be 16 bits. I realize this is a barrier to portability,
  28. but you can change occurrances of "int" to "long" and "short" to "int" if
  29. "long"s are twice the size of "int"s.
  30.  
  31. Note also that model sizes greater than 32K (with 16-bit cells) are likely
  32. to fail because of the sign bit. This has not been adequately tested.
  33.  
  34. The first four sections of the file "common.h" contain implementation-dependent
  35. constants. These are TRACE, BREAKPOINT, several default file names, INITMEM,
  36. MAXMEM, and NSCR. As distributed, the FORTH system will work on most systems,
  37. but especially virtual-memory systems. If you do not have virtual memory, you
  38. will want to change MAXMEM -- see common.h for instructions.
  39.  
  40. Once you've configured common.h to your taste, compile the files with
  41.  
  42.     touch lex.yy.c
  43.     make all
  44.  
  45. Note that lex.yy.c is lex output from forth.lex, slightly modified (using
  46. sed). lex.yy.c is included in the distribution because not everybody has
  47. lex and sed. You touch lex.yy.c before make-ing so make doesn't try to remake
  48. it.
  49.  
  50. This make will create several files. Notable among them are "nf", the
  51. bootstrapper, "forth.core", the core-image output of nf, and "forth", the
  52. interpreter itself. Finally, there are two utility filters, b2l and l2b. These
  53. convert files from block format to line format and back (b2l --> block to
  54. line). A line-format file is one suitable for editing with vi or emacs: it
  55. consists of a header line for each screen, followed by 16 newline-separated
  56. lines of text for that screen, followed by the next screen. THERE MUST ALWAYS
  57. BE SIXTEEN LINES BETWEEN HEADERS in the line file, or l2b won't work properly.
  58.  
  59. You must use l2b to create the block file "forth.block" from "forth.line". Use:
  60.  
  61.     l2b < forth.line > forth.block
  62.  
  63. to do this.  If you don't have I/O redirection, I'm afraid you'll have to
  64. patch these programs (and lex.yy.c and nf.c, for that matter) to take 
  65. arguments or use default files.
  66.  
  67. Note that "forth.block" is the default block file used by FORTH. You can change
  68. this default in "common.h", and you can change it on the FORTH command line
  69. with -f.
  70.  
  71. Now that you have the interpreter ("forth"), the block file
  72. ("forth.block"), and the core file ("forth.core"), you are ready to
  73. roll. Invoke FORTH with the following line to the C-shell:
  74.  
  75.     stty -echo cbreak ; forth ; stty echo -cbreak
  76.  
  77. Some notes while running FORTH:
  78.  
  79. The backspace character is ^H, no matter what your terminal is set for. When
  80. you backspace, ASCII 8 gets sent to the screen, so the cursor should back up
  81. but not erase the letter you're backing up over. There is no kill character
  82. to wipe out an entire line. If you backspace beyond the beginning of the line,
  83. you will get a beep.
  84.  
  85. Don't use tabs; FORTH doesn't recognize them as whitespace.
  86.  
  87. Everything in the FORTH world is upper-case. Use caps-lock if you have one.
  88.  
  89. The VLIST command lists the FORTH vocabulary.
  90.  
  91. Some commands, like LIST and VLIST, use the FORTH word ?TERMINAL to see
  92. if the user wants to quit. Use your interrupt character (usually ^C) to
  93. stop these commands.  If you hit ^C twice before ?TERMINAL is checked,
  94. then you'll get an ABORT back to the FORTH top level. If the FORTH program
  95. is waiting for keyboard input, you'll have to hit ^C twice and then hit
  96. a normal key to see this effect. Your Quit character (often ^\) still works
  97. to get you back to your shell.
  98.  
  99. When you start FORTH up, it will tell you the number of blocks in the
  100. block file (either the default or the one you specified with -f). You can
  101. see a block with the LIST command: "3 LIST" will list block number 3. Block
  102. zero is special: because of a bug in the FORTH standard model, you can't
  103. see block zero until you've accessed many other blocks (where "many" is the
  104. number NSCR from "common.h").
  105.  
  106. In any case, you can load the UNTHREAD utility (see below) with "1 LOAD"
  107. (because it starts on block 1), and the editor with "10 LOAD".
  108.  
  109. FORTH uses "setbuf(stdout,0)" in "forth.c" to force standard output to
  110. be unbuffered.  If this call doesn't work for you, just remove it, and
  111. standard output will be line buffered. If that is the case, change
  112. EXPECT (in "forth.dict"): replace the EMIT call with DROP. Then you can
  113. call forth directly, without the stty stuff. You use your own erase and kill
  114. characters, but the editor won't work.
  115.  
  116. SAVING THE FORTH ENVIRONMENT:
  117.  
  118. When you have been working in FORTH for a while, you will have developed
  119. words which you'd like to save, without having to reload them from the
  120. block file all the time. The word SAVE will save the current core image on
  121. a file, normally "forth.newcore", and exit. The -s flag changes the save
  122. file name.
  123.  
  124. When you start FORTH, the core file (either "forth.core" or the one specified
  125. with -c) is checked to see if it is a saved image or a bootstrapped image.
  126. If it's a saved image, execution begins from the spot it left off from.
  127. If it's bootstrapped (fresh out of nf), execution begins at COLD.
  128.  
  129. SUMMARY OF COMMAND-LINE OPTIONS:
  130.  
  131. -t[n]        trace; n is a digit from 0 to 9, default 0.
  132.  
  133.         Each time through the inner interpreter, a line will be printed
  134. out showing the current stack pointer, the top n stack elements
  135. (topmost at the left), the current interpretive pointer (ip), an indent
  136. to reflect the current nesting depth (actually the return-stack depth),
  137. and the name of the word about to be executed. N is the "trace depth";
  138. see DOTRACE below.
  139.  
  140. -d[n]        debug; n is a digit from 0 to 9, default 0.
  141.  
  142.     Like -t, -d prints out the trace line each time through the inner
  143. interpreter.  Unlike -t, it will then wait for input from the terminal. If
  144. you hit newline (Return, CR, etc.) it will proceed. If you type any key
  145. followed by newline, it will dump the current memory image to the dump file,
  146. usually "forth.dump", and then continue.
  147.  
  148. -n        no setbuf.
  149.     If -n is present, the setbuf(stdout,NULL) call which makes stdout
  150. unbuffered instead of line-buffered will not be executed. This is useful if
  151. you intend to do debugging with -t, -d, or the TRON command (see below).
  152.  
  153. -p xxxx        breakPoint.
  154.     Breakpoints are enabled, and one is set at address xxxx (in hex).
  155. Each time through the inner interpreter, the ip address is checked against
  156. this breakpoint address. If they match, "Breakpoint" is printed, along with
  157. the current stack pointer and the entire contents of the stack, with the
  158. topmost element at the left.
  159.  
  160. -c corename    set the core file name
  161.     The memory image will be read from this file instead of the default,
  162. which is usually "forth.core".
  163.  
  164. -b blockname    set the block file name
  165.     This file will be used as the block file for disk reads and writes,
  166. instead of the default block file, which is usually "forth.block".
  167.  
  168. -s savename    set the core-save file name
  169.     This file will be created or overwritten upon execution of the (SAVE)
  170. primitive (which is called by the SAVE command).  It will contain a core image
  171. (just like forth.core or the -c name) which reflects the current status at the
  172. time of the save. If this file is used as input (renamed to "forth.core" or
  173. used in -c later), the FORTH system will restart right where it left off.
  174. Note that -c and -s MAY use the same name.
  175.  
  176. DEPARTURES FROM THE figFORTH-79 STANDARD:
  177. ---------- ---- --- -------- -- --------
  178.  
  179. There are two features of the FORTH-79 standard which are unimplemented in
  180. this system: the <BUILDS ... DOES> construct and VOCABULARIES. Both of these
  181. are unimplemented simply because I couldn't understand the documentation
  182. sufficiently to implement them.  In any case, they do not affect the operation
  183. of FORTH, except inasmuch as the dictionary is simply a flat stack structure,
  184. and defining-words using DOES simply don't work.
  185.  
  186. EXTENSIONS FROM THE figFORTH-79 STANDARD:
  187. ---------- ---- --- -------- -- --------
  188.  
  189. I grew a FORTH implementation from the Z80 figFORTH standard, and found the
  190. following extensions to be vital to my sanity as a programmer and developer.
  191.  
  192. CASE c1 OF action1 ENDOF c2 OF action2 ENDOF default-action ENDCASE
  193.  
  194. This construct comes from Doctor Dobb's Journal, Number 59, September, 1984,
  195. in an article by Ray Duncan. 
  196.  
  197. I used to find that nesting IFs to emulate a CASE structure was the most
  198. difficult part of programming in FORTH, but now I don't have to mess with
  199. it any more.
  200.  
  201. \ (backslash)
  202.  
  203. This word begins a comment which extends to the end of the current line.
  204. This is only meaningful while loading, and causes an error if you are not
  205. loading.  It amounts to an open-paren where the end of the line is the closing
  206. paren. This, too, comes from Dr. Dobb's Journal, Number 59, in a different
  207. article, by Henry Laxen.
  208.  
  209. TRON, TROFF, DOTRACE
  210.  
  211. These provide tracing facilities for C-FORTH.  TRON takes one parameter, which
  212. is the number of stack elements to show. TROFF disables tracing. DOTRACE
  213. traces once, using the most recent depth value (from TRON or -tn on the command
  214. line). TRON will have no effect (but will still consume its argument) if
  215. the FORTH system was compiled without the TRACE flag set. DOTRACE, however,
  216. will still trace one line as advertised.
  217.  
  218. REFORTH
  219.  
  220. This word is useful when loading screens, to get the user's input. It
  221. reads one line from the terminal (with QUERY) and interprets it (with
  222. INTERPRET), then returns to the caller. This is used in the editor (see
  223. below) to read in the user's terminal type. This is yet another construct
  224. from Ray Duncan's article in Dr. Dobb's Journal, Number 59.
  225.  
  226. ALIAS        usage: ALIAS NEW OLD
  227.  
  228. This word is used to change the meaning of an existing word, after it
  229. has been used in defining other words.  Say you want to change EMIT so
  230. it forces a CR when the current column (user var OUT) equals the number
  231. of characters per line (constant C/L). The current definition of EMIT
  232. is:
  233.  
  234. : EMIT
  235.   (EMIT)
  236.   1 OUT !+
  237. ;
  238.  
  239. You could define a new word, NEWEMIT, as follows:
  240.  
  241. : NEWEMIT
  242.   OUT @ C/L = IF
  243.     CR
  244.   THEN
  245.   (EMIT)
  246.   1 OUT +!
  247. ;
  248.  
  249. and use ALIAS NEWEMIT EMIT to make all previous references to EMIT execute
  250. NEWEMIT instead. This is accomplished by making the definition of EMIT read:
  251.  
  252. : EMIT
  253.   NEWEMIT
  254. ;
  255.  
  256. (Note that my CR sets OUT to zero, so this really would work.)
  257.  
  258. NOTES ON THE BOOTSTRAP DICTIONARY:
  259. ----- -- --- --------- ----------
  260.  
  261. The contents of forth.dict describe the initial FORTH dictionary. There are
  262. several types of things in this file; they will be described by example.
  263.  
  264. PRIM (EMIT) 12        (primitive)
  265.  
  266. This declares a primitive called "(EMIT)", with an execute-code of 12. This
  267. execute-code is an index into the great switch statement in the inner
  268. interpreter, next(). In a real FORTH system, this would be an address where
  269. the actual code for the (EMIT) primitive resided.
  270.  
  271. To add primitives, you must do the following:
  272. 1. Add the primitive to forth.dict, using an unused execute-code.
  273.  
  274. 2. Come up with a name for that primitive which is a legal C identifier.
  275.    Convention for parenthesis, like (EMIT), is PEMIT. For brackets, BEMIT.
  276.    For slash (like "C/L") is CSLL, where SL stands for slash.
  277.  
  278. 3. Add the C identifier name to "forth.h", with the execute-code as its
  279.    value, like this:
  280.  
  281.     #define PEMIT 12
  282.  
  283. 4. In "prims.c", add the code for the primitive, as a function with
  284.    the same name as the #define above, except in lower case:
  285.  
  286.     pemit()
  287.     {
  288.         putchar(pop());
  289.     }
  290.  
  291. 5. In "forth.c", tack another case onto the switch statement in next():
  292.  
  293.             case PEMIT: pemit(); break;
  294.  
  295. 6. Recompile (preferably with make). You will need to recompile everything
  296.    but nf (which uses nf.c, lex.yy.c, and common.h, none of which you
  297.    changed). That is, you need to regenerate "forth" from forth.c, prims.c,
  298.    forth.h, and prims.h, and "forth.core" by throwing "forth.dict" at nf.
  299.  
  300. There is one special primitive: EXECUTE must be primitive number zero, since
  301. it violates structure and jumps into the middle of next(). It is handled as
  302. a special case in the code for NEXT, and it must be primitive number zero.
  303.  
  304. So much for primitives; there are other things in the forth.dict file:
  305.  
  306. CONST C/L 64    (constant)
  307.  
  308. Define constants with the word CONST followed by the name of the constant
  309. and its value.
  310.  
  311. USER OUT 36    (user variable)
  312.  
  313. Define user variables with the word USER followed by the name of the variable
  314. followed by the offset in the user-variable list of that variable.
  315.  
  316. The cold-start values for user variables are defined in common.h; they
  317. get copied into the initial forth.dict by nf, into the "cold-start defaults"
  318. area of memory.  They are copied from there into the first few user-variable
  319. locations by COLD.
  320.  
  321. VAR USE 0    (variable)
  322.  
  323. Define variables with the word VAR followed by the name of the variable
  324. followed by its initial value.
  325.  
  326. : EMIT        (colon-definition)
  327.  
  328. Begin colon-definitions with a colon (of course), followed by the name of
  329. the word.  Follow that with the words which make up the definition, ending
  330. with ; for normal words or ;* for immediate words.
  331.  
  332. There are two special colon-definitions: {NULL} and COLD. {NULL} is a special
  333. symbol which, when it is the name for a colon-definition, gets translated into
  334. a single null byte; the special name '\0'.  This is necessary since you
  335. can't type a null byte into a file, and C would mess up anyway, thinking
  336. the null was a terminator and not part of the string.  COLD is a special word
  337. in that it MUST BE DEFINED. The bootstrapper, nf, compiles the CFA of COLD
  338. into a special place in low memory, where the interpreter knows it can
  339. start executing threaded code.
  340.  
  341. LABEL 
  342.  
  343. Labels are used as the targets of branches. They are handled in much the
  344. same way as colon definitions and other words in the dictionary, in terms
  345. of forward referencing and so on. For this reason, LABELS MUST BE UNIQUE
  346. WORDS. You can't have a label which is the same as any other word in the
  347. dictionary, or you'll get a "word redefined" error (or worse!).
  348.  
  349. Since the "nf" preprocessor does not execute FORTH code, it does not
  350. have the higher-level FORTH constructs like begin .. until or
  351. do .. loop. These must be implemented by the user, using the primitives
  352. BRANCH (unconditional branch), 0BRANCH (branch on top-of-stack == 0),
  353. (DO) (start a DO construct), and (LOOP) and (+LOOP) (the primitives
  354. which end loop constructs).  Each of BRANCH, 0BRANCH, (LOOP), and (+LOOP)
  355. should be followed by one of two things: a signed offset, where a zero
  356. offset branches to the address of the BRANCH (etc.) instruction; or
  357. a label tag, which will be compiled as the appropriate offset from the
  358. current location.
  359.  
  360. A FORTH word with a loop might look like this:
  361.  
  362. : ONE-TO-TEN
  363.   10 0 DO
  364.     I .
  365.   LOOP
  366. ;
  367.  
  368. This would be entered into the "forth.dict" file as follows:
  369.  
  370. : ONE-TO-TEN
  371.   LIT 10 0 (DO)
  372. LABEL LOOP1
  373.     I .
  374.   (LOOP) LOOP1
  375. ;
  376.  
  377. Note the placement of the LABEL directive AFTER the (DO). Note also the use
  378. of LIT before 10, but not before 0. See below under LIT for more details.
  379.  
  380. The branches are used to implement IF ... ELSE ... ENDIF constructs, as
  381. well as conditional looping like BEGIN ... WHILE ... REPEAT and
  382. BEGIN ... UNTIL.  Ordinary programming practices are called for here,
  383. with such standbys as branching over the "TRUE" branch of the IF when
  384. the predicate is false, and branching over the "FALSE" part after the
  385. TRUE part has executed (if the predicate was true).  If you need more
  386. guidance, study forth.dict, or don't bother.
  387.  
  388. " (quotation mark)
  389.  
  390. The quotation mark begins and ends a "STRING LITERAL", which is compiled
  391. into the dictionary as a count byte followed by the bytes in the string,
  392. from left to right.  This is useful for the primitive (."), which expects
  393. a string of this form to follow it in the dictionary.  Within quotation
  394. marks, a backslash (\) will escape any character, including a quotation
  395. mark or another backslash, so:
  396.  
  397.     "He said, \"Backslash (\\) is best.\""
  398.         produces
  399.     [33] He said, "Backslash (\) is best."
  400.  
  401. where [33] is the length count.
  402.  
  403. Note that backslash escape conventions like \n, \t, etc. DO NOT WORK
  404. IN STRING LITERALS. This is a bug, not a feature.
  405.  
  406. 'x' (character literal surrounded by apostrophes)
  407.  
  408. Character-literal translation is done between single quotes, with the
  409. following effects:
  410.  
  411.     Text    produces
  412.     'A'       the value of the character A.
  413.     '\b'       system-dependent backspace character
  414.     '\f'                form-feed 
  415.     '\n'                newline
  416.     '\r'                carriage return
  417.     '\t'                tab
  418.     '\\'       the value of the character backslash
  419.     '''       the value of the character apostrophe.
  420.  
  421. These values are only meaningfully used after LIT commands; see below.
  422.  
  423. LIT
  424.  
  425. LIT must be used before all literal values in the dictionary, just as it
  426. is used (though the user doesn't see it) when words are defined. The
  427. forth.dict file, after all, represents a de-compiled FORTH memory image.
  428. It has all the BRANCHes and (LOOP)s showing, and it also has LITs showing.
  429.  
  430. In the above example for looping, LIT was used before 10, but not before
  431. 0. This is because "0" is defined a a CONSTant earlier in the forth.dict
  432. file.  To keep this straight, you should keep the following in mind:
  433. When you are in the middle of a definition, each word you type will have
  434. its CFA compiled into the dictionary.  If the word you type is not defined
  435. yet, nf looks at its "hint" about the string of characters: do they form a
  436. number, like a one and a zero form ten?  Do they form a hexadecimal number,
  437. like 0x10? Is it an octal literal, like 077? Is it a character literal, 
  438. like 'A'? If none of these is the case, then a zero is compiled as a place
  439. holder, and the word is considered a FORWARD REFERENCE to something yet to
  440. be defined. 
  441.  
  442. Yes, forward references are handled, and the distinction of
  443. defined words and labels is preserved: labels, instead of compiling their
  444. CFA into the dictionary, compile the offset of their CFA from the current
  445. dictionary pointer (minus one). If, at the end of the input file, there
  446. are still unresolved forward references, they will be listed. If the
  447. words containing the forward references are never executed, there will
  448. be no problem. If those words ARE executed, FORTH will bomb with a message
  449. like "Attempt to execute illegal primitive."
  450.  
  451. One snag is that you have to remember what numbers are defined as CONSTants,
  452. and what numbers aren't. If nf sees "LIT 1" it will compile the CFA of LIT,
  453. then the CFA of 1, because 1 has already been defined as a constant.
  454.  
  455. LIT must precede decimal, hex, octal, and character literals, but not 
  456. string literals.  If one of these literals is not preceded by LIT, a
  457. warning is issued, since this is unusual behavior. No warning is issued
  458. if LIT is succeeded by something other than a literal-class item, because
  459. that is not so unusual.
  460.  
  461.  
  462. INSTALLER'S GUIDE FOR THE SCREEN EDITOR:
  463. --------- - ----- --- --- ------ ------
  464.  
  465. This is an editor which I wrote on my Osborne 1, which has a memory-mapped
  466. display. I hacked out that part and hacked in the screen updating using .LINE,
  467. but at anything lower than 9600 BAUD I expect this to be intolerable.
  468.  
  469. When you get FORTH at your site, you will have to edit the line-file to
  470. include functions which clear the screen, locate the cursor, and enter and
  471. exit standout mode, named CLS, LOCATE, STANDOUT, and STANDEND, respectively.
  472. The trick for installing this is to put those functions in an unused screen
  473. (screens 8 and 9 are perfect for this), and place a CONSTANT in screen 10
  474. which is the name of the terminal (like "H19" or "ACT5") and has a value
  475. which is the number of the screen you put its definition in.  VT100 and
  476. ADM5 are included as models, in screens 6 and 7. ADM5 actually covers
  477. a broad range of terminals, from the old ADM3A to the TVI920C, though
  478. standout might not work the same any more. The two words STANDOUT and
  479. STANDEND can be null words, anyway.
  480.  
  481. USER'S GUIDE FOR THE EDITOR:
  482. ---- - ----- --- --- ------
  483.  
  484. This is a screen editor for FORTH screens. It will alter the file
  485. "forth.block" in the current directory, or whatever the installer set
  486. the default blockfile to be, or whatever you specify on the command
  487. line with the "-b file" switch.
  488.  
  489. You call a screen up with the EDIT command:
  490.  
  491.     3 EDIT
  492.  
  493. will begin editing screen 3.  The file starts with screen 0, but, due to
  494. a bug in figFORTH which I have carefully preserved (:-), you can't see
  495. screen 0 until you've edited several others -- as many as fit in memory,
  496. in fact. This number is 5 at the outset, but can be as low as 2 or as
  497. many as your installer's whim dictated. In any case, stick with screens
  498. numbered from 1 to the size of the block file as displayed when you
  499. started FORTH. 
  500.  
  501. When you start editing, the screen will clear, and the screen you asked
  502. for will appear. FORTH "screens" are, by convention and convenience,
  503. sixteen lines by sixty-four characters, for a total of 1K per screen.
  504. At the bottom of the screen being edited will be the word SCREEN and
  505. this screen's number.
  506.  
  507. The keys (as I've distributed the editor) match WordStar, to some extent.
  508. The cursor movement keys do, at any rate: ^E, ^D, ^X, ^S form a movement
  509. triangle at the left-hand side of the keyboard, moving one character or
  510. line at a time. The outer reaches of this triangle move even farther: 
  511. ^A and ^F move one word backward and forward, and ^R and ^C move one
  512. SCREEN backward and forward. If ^C is already your interrupt character,
  513. don't panic: use ESC-C (escape is a meta-prefix like in Emacs). If your
  514. network won't let you send ^S (like Sytek), ^H will do for backspace.
  515.  
  516. To see all the key bindings, use the FORTH command DESCRIBE-BINDINGS.
  517. To make a binding, do this:
  518.     1. Type "BIND-TO-KEY function <CR>"  where function is the name
  519.        of the command you want bound to a key, and <CR> means press
  520.        return/newline.
  521.     2. The computer will print "KEY: " at which time you should
  522.        strike the key you want to have that function bound to.
  523.        If you want something bound to ESC plus something, just press
  524.        escape followed by the key, exactly as you intend to use the
  525.        key in practice.
  526.  
  527. To see the binding for one key, use the command DESCRIBE-KEY. Again,
  528. you will be asked for the key you want described. Strike the key just
  529. as you normally do, with ESC before it if necessary.
  530.  
  531. The initial bindings are on screens 27 and 28 of the block file.
  532.  
  533. The editor is always in replace mode. That is, when you strike a key, it
  534. overwrites whatever was under the cursor.  There is no insert mode; I haven't
  535. gotten around to that.
  536.  
  537. As you go around changing things, you are only changing the image of the
  538. screen which FORTH keeps in memory; you are not changing the block file.
  539. You can mark the current screen for updating to the blockfile with ^U.
  540. This only marks the screen; it won't be written to the blockfile until
  541. the space is needed again, or you explicitly FLUSH the memory buffers.
  542. Use ESC-F (press escape, then press capital F) to mark the current screen
  543. for updating, and then FLUSH all marked screens (including this one, now)
  544. to the block file. Once you've done that, the change is permanent.
  545.  
  546. If you really mean to make a given change to a screen, mark it as updated
  547. (^U) right away. Countless hours have been wasted changing screens without
  548. marking them for writing, and then having that memory reused -- the changes
  549. are lost.
  550.  
  551. You can leave the editor with ESC-Q (for Quit).  Be sure to do an ESC-F
  552. before you do, if you want to save what you have. You can never be sure
  553. if your changes will get written out if you don't. (Yes, I know this
  554. is an oversimplification.)
  555.  
  556. You can leave FORTH by typing BYE.
  557.  
  558. FINAL NOTES FROM THE AUTHOR:
  559. ----- ----- ---- --- ------
  560.  
  561. FORTH runs slowly. If anybody can make this turkey fly (without, of course,
  562. rewriting it in assembly language), more power to you.  It was done as a
  563. Junior project at Indiana University, but in fact I learned more about
  564. project management and programmer/systems staff interaction than I did
  565. about implementing FORTH (which I had done previously in 8080 assembly
  566. code). In that sense it was profitable, and, since it works, I see no reason
  567. not to distribute it to the network. If you have comments of praise,
  568. I can be reached through the summer of 1985 at the address below;
  569. after that, I MAY be at iuvax!apratt.  Comments of another nature
  570. are not enthusiastically solicited, and I do NOT expect to upgrade this
  571. implementation AT ALL, EVER. Sorry, but there will be no "Version 2" for 
  572. this baby. If I have left crucial points out of this documentation,
  573. and my (hopefully-well-commented) code doesn't provide the answer,
  574. I will reply and possibly improve this documentation.  But for the
  575. most part, you're on your own.
  576.  
  577. As a parting shot, the inner interpreter's "switch" statement could
  578. be replaced by an array of functions, using the variable p as an
  579. index. I was not that ambitious, and I don't know if it would be faster
  580. than the table-lookup which my C compiler generates.
  581.  
  582.                     -- Allan Pratt
  583.                     APRATT.PA@XEROX.ARPA
  584.  
  585. QUICK SUMMARY OF FILES (THERE IS A MESS OF THEM!)
  586.  
  587. Makefile    supposed to bring them all together
  588. b2l.c and b2l    filter to convert block-files into line-files for editing
  589. l2b.c and l2b    filter to convert line-files into block-files for FORTH
  590.  
  591. common.h    This is a header file with configuration and common information
  592.         used by all C source files except lex.yy.c
  593.  
  594. forth.h        Header file with primitive numbers in it, among other things
  595. forth.c        source code for the guts/support functions for the interpreter
  596. prims.h        Header file with macro definitions for primitives
  597. prims.c        source code for primitives too complex for macros
  598.  
  599.         The above four files, plus common.h, contribute to the
  600.         executable "forth"
  601.  
  602. nf.c        source for the bootstrapper, which interprets the dictionary
  603.         and generates an initial memory image for FORTH
  604.  
  605. forth.lex    lex input for lexical analyzer used by nf.c
  606. forth.lex.h    header file used by lex.yy.c and nf.c
  607. lex.yy.c    lex output, modified (look at the Makefile)
  608.  
  609.         The above four files, plus common.h, contribute to the
  610.         executable "nf", the preprocessor.
  611.  
  612. forth.block    This is the (default) block-file used by FORTH for its
  613.         editing- and load-screens
  614.  
  615. forth.line    This file usually resembles forth.block, but is in a
  616.         format suitable for editing with emacs or vi: a header
  617.         line, followed by sixteen lines of trailing-blank-
  618.         truncated, newline-terminated text for each screen.
  619.  
  620.         If one of forth.line and forth.block is out of date with
  621.         respect to the other, you can bring it back up to date
  622.         with b2l or l2b, above.
  623.  
  624. forth.dict    This is a human-readable, pseudo-FORTH dictionary which
  625.         nf uses to generate the initial environment. It contains
  626.         forward references and no higher structures like DO..LOOP
  627.  
  628. forth.core    This is one output of nf: it contains the core image for
  629.         the FORTH environment, as dictated by common.h and forth.dict
  630.  
  631. forth.newcore    This is the file for holding core images saved with the (SAVE)
  632.         primitive. If FORTH is started with "-c forth.newcore", the
  633.         image is restarted right where it left off.
  634.  
  635. forth.map    This is another output of nf: it contains a human-readable
  636.         dump of the forth environment which nf generated. This can
  637.         be compared with the post-mortem dump which FORTH generates
  638.         in forth.dump in certain cases.
  639.  
  640.